#pragma once

#include <iostream>
#include <opencv2/core/mat.hpp>
#include <opencv2/opencv.hpp>

#define C_SHARP_MAX_OBJECTS 1000

/**
 * @brief 边界框结构体,用于存储目标检测结果
 */
struct bbox_t {
    int id = -1;                 // 目标类别ID
    float prob = 0.f;            // 检测置信度
    unsigned int x{}, y{}, w{}, h{}; // 边界框坐标(x,y)和宽高(w,h)
};

/**
 * @brief 图像数据结构体,存储不同格式的图像数据
 */
struct image_t {
    cv::Mat rgbf;   // 浮点型RGB图像
    cv::Mat rgb8;   // 8位RGB图像
    cv::Mat rgb16;  // 16位RGB图像

    int h = 0;      // 图像高度
    int w = 0;      // 图像宽度
    int c = 0;      // 图像通道数
};

/**
 * @brief 目标检测模型输入输出数据结构体
 */
struct st_dlm_data
{
    image_t img;    // 输入图像

    float prob_threshold = 0.3f;  // 置信度阈值
    float nms_threshold = 0.5f;   // 非极大值抑制阈值

    bbox_t result_boxs[C_SHARP_MAX_OBJECTS];  // 检测结果边界框数组
    int result_box_num = 0;                   // 检测到的边界框数量
};

/**
 * @brief 边界框容器结构体
 */
struct bbox_t_container {
    bbox_t candidates[C_SHARP_MAX_OBJECTS];  // 候选边界框数组
};

/**
 * @brief 模型精度模式枚举
 */
enum PRECISION_MODE
{
    PRECISION_FP32,  // 32位浮点精度
    PRECISION_FP16,  // 16位浮点精度
    PRECISION_INT8,  // 8位整数精度
};

/**
 * @brief 模型转换输入参数结构体
 */
struct st_trans_model_input 
{
    std::string cfg_path;     // 配置文件路径
    std::string model_path;   // 模型文件路径

    PRECISION_MODE precision = PRECISION_FP16;  // 精度模式
    std::string gpu_model = "NVIDIA GeForce RTX 3060";  // GPU型号

    std::string trans_path;   // 转换后的模型保存路径
};

/**
 * @brief 加密头部结构体
 */
struct st_encrypt_header {
    size_t struct_size;  // 结构体大小
    size_t xml_size;     // XML文件大小
    size_t bin_size;     // 二进制文件大小
};

static constexpr int MAX_NUM_ANCHORS = 4;  // 最大锚框数量
static constexpr int MAX_STRIDES = 4;      // 最大步长数量

/**
 * @brief OpenVINO模型加密信息结构体
 */
struct st_encrypt_info_ovino {
    char gpu_model[100] = {0};  // GPU型号

    int batch_size = 0;     // 批处理大小
    int class_num = 0;      // 类别数量
    int input_channel = 0;  // 输入通道数
    int image_width = 0;    // 图像宽度
    int image_height = 0;   // 图像高度

    int num_anchors_size = 0;           // 锚框数量大小
    int num_anchors[MAX_NUM_ANCHORS] = {0};  // 锚框数组

    int stride_num = 0;              // 步长数量
    int strides[MAX_STRIDES] = {0};  // 步长数组

    bool dynamic = false;   // 是否为动态模型
    int engine_size = 0;    // 引擎大小

    float obj_threshold{};  // 目标检测阈值
    float nms_threshold{}; // 非极大值抑制阈值
};